/******************************************************************************* * Signavio Core Components * Copyright (C) 2012 Signavio GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. ******************************************************************************/ package de.hpi.bpmn2_0.factory.node; import java.util.ArrayList; import java.util.List; import org.oryxeditor.server.diagram.generic.GenericEdge; import org.oryxeditor.server.diagram.generic.GenericShape; import de.hpi.bpmn2_0.annotations.StencilId; import de.hpi.bpmn2_0.exceptions.BpmnConverterException; import de.hpi.bpmn2_0.factory.AbstractShapeFactory; import de.hpi.bpmn2_0.factory.BPMNElement; import de.hpi.bpmn2_0.factory.configuration.Configuration; import de.hpi.bpmn2_0.model.BaseElement; import de.hpi.bpmn2_0.model.Collaboration; import de.hpi.bpmn2_0.model.Definitions; import de.hpi.bpmn2_0.model.artifacts.Artifact; import de.hpi.bpmn2_0.model.connector.Association; import de.hpi.bpmn2_0.model.connector.MessageFlow; import de.hpi.bpmn2_0.model.conversation.CallConversation; import de.hpi.bpmn2_0.model.conversation.Conversation; import de.hpi.bpmn2_0.model.conversation.ConversationLink; import de.hpi.bpmn2_0.model.conversation.ConversationNode; import de.hpi.bpmn2_0.model.conversation.SubConversation; import de.hpi.bpmn2_0.model.extension.signavio.SignavioMetaData; import de.hpi.bpmn2_0.model.participant.Participant; import de.hpi.bpmn2_0.util.DiagramHelper; /** * Factory that creates communication and conversation elements * * @author Sven Wagner-Boysen * */ @StencilId( { "Communication", "SubConversation" }) public class ConversationFactory extends AbstractShapeFactory { public BPMNElement createBpmnElement(GenericShape shape, Configuration configuration) throws BpmnConverterException { BPMNElement bpmnElement = super.createBpmnElement(shape, configuration); if(bpmnElement != null && bpmnElement.getNode() != null) { handleLinkedDiagrams(bpmnElement.getNode(), shape, configuration); } return bpmnElement; } /* * (non-Javadoc) * * @seede.hpi.bpmn2_0.factory.AbstractBpmnFactory#createProcessElement(org. * oryxeditor.server.diagram.Shape) */ // @Override protected ConversationNode createProcessElement(GenericShape shape) throws BpmnConverterException { try { ConversationNode node = (ConversationNode) this .invokeCreatorMethod(shape); node.setName(shape.getProperty("name")); node.setId(shape.getResourceId()); node = convertToCallConversation(shape, node); return node; } catch (Exception e) { throw new BpmnConverterException( "Error while creating the process element of " + shape.getStencilId(), e); } } /** * Creates the process element for a call conversation. * * @param shape * The resource shape * @return The {@link CallConversation} */ public ConversationNode convertToCallConversation(GenericShape shape, ConversationNode node) { String isCallConversation = shape.getProperty("iscallconversation"); if(isCallConversation != null && isCallConversation.equals("true")) { return new CallConversation(node); } else { return node; } } @StencilId("Communication") public Conversation createConversation(GenericShape shape) { return new Conversation(); } @StencilId("SubConversation") public SubConversation createSubConversation(GenericShape shape) { return new SubConversation(); } private List<String> getParticipantIds(GenericShape<?,?> shape) { List<String> participantIds = new ArrayList<String>(); /* Check outgoing conversation links */ for (GenericEdge connector : DiagramHelper.getOutgoingEdges(shape)) { if (!connector.getStencilId().equals("ConversationLink")) continue; if (connector.getTarget() != null && connector.getTarget().getStencilId().equals( "Participant")) participantIds.add(connector.getTarget().getResourceId()); } /* Check incomming conversation links */ for (GenericEdge<?,?> connector : DiagramHelper.getIncomingEdges(shape)) { if (!connector.getStencilId().equals("ConversationLink")) continue; for (GenericShape part : connector.getIncomingsReadOnly()) { if (part.getStencilId().equals("Participant")) participantIds.add(part.getResourceId()); } } return participantIds; } /** * Transforms linked diagrams of collapsed subprocess and event subprocess. * * @param baseElement * @param shape * @param config */ private void handleLinkedDiagrams(BaseElement baseElement, GenericShape shape, Configuration config) { if(baseElement == null || !shape.getStencilId().matches(".*SubConversation.*")) { return; } /* * Diagram Link */ String entry = shape.getProperty("entry"); if(entry == null || entry.length() == 0) { return; } SignavioMetaData metaData = new SignavioMetaData("entry", entry); baseElement.getOrCreateExtensionElements().add(metaData); Definitions linkedDiagram = SubprocessFactory.retrieveDefinitionsOfLinkedDiagram(entry, config); if(linkedDiagram == null || linkedDiagram.getRootElement().size() == 0) { return; } for(BaseElement rootEl : linkedDiagram.getRootElement()) { if(rootEl instanceof Collaboration) { Collaboration linkedCon = (Collaboration) rootEl; /* Sub choreography */ if(baseElement instanceof SubConversation) { SubConversation subConversation = (SubConversation) baseElement; /* * Add conversation nodes, links, participants, * artifacts, associations, message flows */ for(ConversationNode node : linkedCon.getConversationNode()) { subConversation.getConversationNode().add(node); subConversation._diagramElements.add(node._diagramElement); } for(ConversationLink link : linkedCon.getConversationLink()) { subConversation.getConversationLink().add(link); subConversation._diagramElements.add(link._diagramElement); } for(Artifact a : linkedCon.getArtifact()) { subConversation.getArtifact().add(a); subConversation._diagramElements.add(a._diagramElement); } for(MessageFlow m : linkedCon.getMessageFlow()) { subConversation.getMessageFlow().add(m); subConversation._diagramElements.add(m._diagramElement); } for(Participant p : linkedCon.getParticipant()) { subConversation.getParticipantRef().add(p); subConversation._diagramElements.add(p._diagramElement); } for(Association associ : linkedCon.getAssociation()) { subConversation.getAssociation().add(associ); subConversation._diagramElements.add(associ._diagramElement); } } /* Call choreography */ else if(baseElement instanceof CallConversation) { CallConversation callConversation = (CallConversation) baseElement; callConversation.setCalledElementRef(linkedCon); for(BaseElement baseEl : linkedCon.getChilds()) { callConversation._diagramElements.add(baseEl._diagramElement); } } } } } }